package com.jsaas.core.security;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collection;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;

import com.jfinal.log.Log;
import com.jfinal.plugin.ehcache.CacheKit;
import com.jfinal.plugin.redis.Redis;

/**
 * @ClassName: onlineSessionDao
 * @Description: session管理，获取在线用户等(session持久化，配合nginx负载均衡，实现共享session)
 * @author tuozq
 * @date 2017年11月3日 上午9:48:01
 *
 */
public class OnlineSessionDao extends EnterpriseCacheSessionDAO {

	private static final Log log = Log.getLog(OnlineSessionDao.class);
	
	//定义sessionDao缓存的前缀，可以通过 Redis.use().getJedis().keys(OnlineSessionDao.cacheNamePrefix + "*") 获取到sessionDao缓存的所有session
	public static final String cacheNamePrefix = "shiro_sessionDao_cache:";
	
	private void set(String key, Object value){
		Redis.use().set(cacheNamePrefix + key, value);
	}
	
	private Object get(String key){
		return Redis.use().get(cacheNamePrefix + key);
	}
	
	private void remove(String key){
		Redis.use().del(cacheNamePrefix + key); 
	}
	
	/**
	 * 创建session
	 */
	@Override
	public Serializable doCreate(Session session) {
		Serializable sessionId = super.doCreate(session);
		log.info("创建  Session:"+session.getHost() + ";" + session.getId());
		set(session.getId().toString(), sessionToByte(session));
		return sessionId;
	}
	
	
	/**
	 * 删除session
	 */
	@Override
	public void doDelete(Session session) {
		log.info("删除 Session:"+session.getHost() + ";" + session.getId());
		remove(session.getId().toString());
		super.doDelete(session);
	}

	/**
	 * 更新session的最后一次访问时间
	 */
	@Override
	public void doUpdate(Session session) throws UnknownSessionException {
		log.info("更新 Session:"+session.getHost() + ";" + session.getId());
		set(session.getId().toString(), sessionToByte(session));
		super.doUpdate(session);

	}

	/**
	 * 获取session
	 */
	@Override
	protected Session doReadSession(Serializable sessionId) {
		Session session = super.doReadSession(sessionId);
		if(session == null){
			byte[] bytes = (byte[]) get(sessionId.toString());
			if(bytes != null && bytes.length > 0){
				session = byteToSession(bytes);
			}
		}
		return session;
	}
	

	// 把session对象转化为byte保存到缓存中
	public byte[] sessionToByte(Session session){
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		byte[] bytes = null;
		try {
			ObjectOutputStream oo = new ObjectOutputStream(bo);
			oo.writeObject(session);
			bytes = bo.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bytes;
	}

	// 把byte还原为session
	public Session byteToSession(byte[] bytes){
		ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
		ObjectInputStream in;
		SimpleSession session = null;
		try {
			in = new ObjectInputStream(bi);
			session = (SimpleSession) in.readObject();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return session;
	}
}
